package cn.xyfmzmy.spring;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * 如果把 ApplicaitonContext比作生产Bean工厂
 * Bean就是生产的产品
 * BeanDefinition就是产品的设计图
 */
public class BeanDefinition {

    private String name;        // bean对象的名字
    private Constructor<?> constructor;     // 构造函数
    private Method postConstructMethod;     // postConstruct函数
    private List<Field> autowiredFields;    // 需要autowired的属性
    private Class<?> beanType;              // bean对象的类型

    public BeanDefinition(Class<?> type) {
        this.beanType = type;
        Componet componet = type.getDeclaredAnnotation(Componet.class);
        // bean对象的名字为componet注解的name属性，name属性为空就为类名
        this.name = componet.name().isEmpty() ? type.getSimpleName() : componet.name();
        try {
            this.constructor = type.getConstructor();
            // 找是否有@PostConstruct修饰的函数
            this.postConstructMethod = Arrays.asList(type.getMethods()).stream()
                    .filter( m -> m.isAnnotationPresent(PostConstruct.class))
                    .findFirst()                // 有就获取第一个(这里只支持一个)
                    .orElse(null);        // 没有就为null
            // 找被@Autowired修饰的属性
            this.autowiredFields = Arrays.asList(type.getDeclaredFields()).stream()
                    .filter( f -> f.isAnnotationPresent(Autowired.class))
                    .toList();
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

    public String getName(){ return name;}

    public Constructor<?> getConstructor(){
        return constructor;
    }

    public Method getPostConstructMethod(){
        return postConstructMethod;
    }

    public Class<?> getBeanType() {
        return beanType;
    }

    public List<Field> getAutowiredFields() {
        return autowiredFields;
    }
}
